/**
 * Copyright @ 2010-2015 Hex company All rights reserved
 * 系统名称：DCP
 * 模块名称：
 *
 * @version版本信息：V1.0
 * @author:jiewang
 */
package com.hex.ds.hdrs.common.excel;

import com.hex.bigdata.hbda.utils.StringUtils;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.utils.HdrsDateUtil;
import org.apache.poi.ss.usermodel.Sheet;

import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UploadCycleJobExcelHelper {
    /**
     * 获取EXCEL里面的数值
     * <p>
     * (去首尾空字符串、去除字符串中所有反分号、反单引号、单引号、回车、换行符)
     *
     * @param sheet
     * @param rowNo
     * @param cellNo
     * @return String
     */
    public static String getValueByRowCeNo(Sheet sheet, int rowNo, int cellNo) {
        String dest = "";
        // 是否为空值
        if (sheet != null) {
//            dest = ExcelHelper.getCellVal(sheet.getRow(rowNo), cellNo).trim();
            dest = replaceBlank(dest);
        }
        return dest;
    }

    /**
     * 去除字符串中所有分号、反单引号、单引号、回车、换行符
     *
     * @param str
     * @return true:成功 false:失败
     */
    public static String replaceBlank(String str) {
        String dest = "";
        String regex = ";|`|'|\r|\n";
        // str 是否为 null
        if (str != null) {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    /**
     * 去除字符串中所有反单引号
     *
     * @param str
     * @return true:成功 false:失败
     */
    public static String replaceBlank2(String str) {
        String dest = "";
        String regex = "`";
        // str 是否为 null
        if (str != null) {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    /**
     * 获取EXCEL里面的数值
     * <p>
     * (不做任何处理)
     *
     * @param sheet
     * @param rowNo
     * @param cellNo
     * @return String
     */
    public static String getValueByRowCeNo3(Sheet sheet, int rowNo, int cellNo) {
        String dest = "";
        // 是否为空值
        if (sheet != null) {
//            dest = ExcelHelper.getCellVal(sheet.getRow(rowNo), cellNo);
        }
        return dest;
    }

    /**
     * 获取序号
     *
     * @param sheet
     * @return
     */
    public static String getIndex(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 0);
    }

    /**
     * 获取作业编号
     *
     * @param sheet
     * @return
     */
    public static String getJobCode(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 1);
    }

    /*
     * @Method: checkJobCode <br>
     * @Param: [jobCode, rowIndex, dbCycleJobMap, operator] <br>
     * @Return: java.lang.String <br>
     * @Description：检查作业编码<br>
     * @Author： Dong shiyi<br>
     * @Date： 2021/5/27 11:06 <br>
     * @Version： V1.0<br>
     */
    public static String checkJobCode(String jobCode, Integer rowIndex, Map<String, String> dbCycleJobMap, String operator) {
        Pattern pattern = Pattern.compile("^[0-9A-Z_|()=>.-]+$");
        if (StringUtils.isBlank(jobCode)) {
            return "第" + rowIndex + "行的作业编码为空,请核对后再上传。";
        } else {
            Matcher matcher = pattern.matcher(jobCode);
            if (!matcher.matches()) {
                return "第" + rowIndex + "行的作业编码只能输入大写英文字母、下划线、分隔符或数字及指定符号(=>.-)";
            } else if (jobCode.length() > 100) {
                return "第" + rowIndex + "行的作业编码长度不能大于100位";
            }
        }
        if (dbCycleJobMap.containsKey(jobCode) && Const.JOB_DEF_UPLOAD_ADD_OPERATOR.equals(operator)) {
            return "第" + rowIndex + "行的作业编码:" + jobCode + "已存在,无法新增,请核对后再上传。";
        }
        if (!dbCycleJobMap.containsKey(jobCode) && (Const.JOB_DEF_UPLOAD_DEL_OPERATOR.equals(operator) || Const.JOB_DEF_UPLOAD_UP_OPERATOR.equals(operator))) {
            return "第" + rowIndex + "行的作业编码:" + jobCode + "不存在,请核对后再上传。";
        }
        return null;
    }

    /**
     * 获取作业名称
     *
     * @param sheet
     * @return
     */
    public static String getJobName(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 2);
    }


    /**
     * 获取任务编码
     *
     * @param sheet
     * @return
     */
    public static String getTaskCode(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 3);
    }

    /**
     * @Method: getLabelCodeList
     * @Param: [sheet, rowIndex]
     * @Return: java.lang.String
     * @Description: 获取标签编码集合
     * @Author: ji.tang
     * @Date: 2022/3/31 19:03
     * @Version: V1.0
     */
    public static String getLabelCodeList(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 26);
    }

    /**
     * @Method: getPlanExecDuration 
     * @Param: [sheet, rowIndex] 
     * @Return: java.lang.String 
     * @Description: 获取预计执行时长
     * @Author: ji.tang
     * @Date: 2022/12/9 14:06 
     * @Version: V1.0
     */
    public static String getPlanExecDuration(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 27);
    }

    public static String checkTaskCode(String taskCode, Integer rowIndex, List<String> taskCodeList,
                                       Map<String, String> dbCycleTaskMap, String operator) {
        Pattern pattern = Pattern.compile("^[0-9A-Z_|()=>.-]+$");
        if (StringUtils.isBlank(taskCode)) {
            return "第" + rowIndex + "行的任务编码为空,请核对后再上传。";
        } else {
            Matcher matcher = pattern.matcher(taskCode);
            if (!matcher.matches()) {
                return "第" + rowIndex + "行的任务编码只能输入大写英文字母、下划线、分隔符或数字及指定符号(=>.-)";
            }
        }
        if (taskCodeList.contains(taskCode)) {
            return "第" + rowIndex + "行的任务编码:" + taskCode + "重复,请核对后再上传。";
        }
        if (dbCycleTaskMap.containsKey(taskCode) && Const.JOB_DEF_UPLOAD_ADD_OPERATOR.equals(operator)) {
            return "第" + rowIndex + "行的任务编码:" + taskCode + "已存在,请核对后再上传。";
        }
        return null;
    }

    /**
     * 获取任务名称
     *
     * @param sheet
     * @return
     */
    public static String getTaskName(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 4);
    }

    /**
     * 获取脚本执行命令
     *
     * @param sheet
     * @return
     */
    public static String getSheelPath(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 5);
    }

    public static String checkSheelPath(String shellPath, Integer rowIndex) {
        if (StringUtils.isBlank(shellPath)) {
            return "第" + rowIndex + "行的脚本执行命令为空,请核对后再上传。";
        }
        return null;
    }

    /**
     * 获取脚本执行参数
     *
     * @param sheet
     * @return
     */
    public static String getSheelParam(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 6);
    }

    /**
     * @Method: getIsSingleJob
     * @Param: [sheet, rowIndex]
     * @Return: java.lang.String
     * @Description： 获取是否单次作业
     * @Author： jd.chen
     * @Date： 2021/5/27 11:17
     * @Version： V1.0
     */
    public static String getIsSingleJob(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 7);
    }

    /**
     * @Method: checkIsSingleJob
     * @Param: [isSingleJob, rowIndex]
     * @Return: java.lang.String
     * @Description： 检查是否单次作业
     * @Author： jd.chen
     * @Date： 2021/5/27 11:17
     * @Version： V1.0
     */
    public static String checkIsSingleJob(String isSingleJob, Integer rowIndex) {
        if (StringUtils.isBlank(isSingleJob)) {
            return "第" + rowIndex + "行的是否单次作业为空,请核对后再上传。";
        } else if (Const.IS_SINGLE_JOB_CN.equals(isSingleJob) || Const.NOT_SINGLE_JOB_CN.equals(isSingleJob)) {

        } else {
            return "第" + rowIndex + "行的是否单次作业参数输入有误，举例：是、否";
        }
        return null;
    }

    /**
     * @Method: getBizDate
     * @Param: [sheet, rowIndex]
     * @Return: java.lang.String
     * @Description：获取业务日期
     * @Author： jd.chen
     * @Date： 2021/5/27 11:18
     * @Version： V1.0
     */
    public static String getBizDate(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 8);
    }

    /**
     * @Method: checkBizDate
     * @Param: [isSingleJob, bizDate, rowIndex]
     * @Return: java.lang.String
     * @Description： 检查业务日期
     * @Author： jd.chen
     * @Date： 2021/5/27 11:30
     * @Version： V1.0
     */
    public static String checkBizDate(String isSingleJob, String bizDate, Integer rowIndex) {
        if (Const.IS_SINGLE_JOB_CN.equals(isSingleJob) && StringUtils.isBlank(bizDate)) {
            return "第" + rowIndex + "行的是单次作业,业务日期不允许为空,请核对后再上传。";
        }
        return null;
    }

    /**
     * 获取调度间隔
     *
     * @param sheet
     * @return
     */
    public static String getJobPeriod(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 9);
    }

    public static String getJobPeriodValue(String jobPeriod) {
        if (StringUtils.isNotBlank(jobPeriod)) {
            int index = jobPeriod.indexOf("[");
            jobPeriod = (-1 != index) ? jobPeriod.substring(0, index) : jobPeriod;
            if ("W".equals(jobPeriod) || "周".equals(jobPeriod)) {
                return "W";
            }
            if ("X".equals(jobPeriod) || "旬".equals(jobPeriod)) {
                return "X";
            }
            if ("M".equals(jobPeriod) || "月".equals(jobPeriod)) {
                return "M";
            }
            if ("Q".equals(jobPeriod) || "季".equals(jobPeriod)) {
                return "Q";
            }
            if ("Y".equals(jobPeriod) || "年".equals(jobPeriod)) {
                return "Y";
            }
            if ("O".equals(jobPeriod) || "自定义".equals(jobPeriod)) {
                return "Y";
            }
        }
        return "D";
    }

    public static String getDateExpression(String jobPeriod) {
        if (StringUtils.isNotBlank(jobPeriod)) {
            int index = jobPeriod.indexOf("[");
            if (index != -1) {
                return jobPeriod.substring(jobPeriod.indexOf("[") + 1, jobPeriod.indexOf("]"));
            }
        }
        return null;
    }

    /**
     * 获取偏移小时
     *
     * @param sheet
     * @return
     */
    public static String getOffsetHour(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 10);
    }

    /**
     * 获取任务优先级
     *
     * @param sheet
     * @return
     */
    public static String getTaskPriorityLevel(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 11);
    }

    /**
     * 获取作业状态
     *
     * @param sheet
     * @return
     */
    public static String getJobStatus(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 12);
    }

    public static String getJobStatusValue(String jobStatus) {
        if ("启用".equals(jobStatus)) {
            return Const.EABLE;
        }
        if ("停用".equals(jobStatus)) {
            return Const.UNENABLE;
        }
        return Const.UNPUBLISHED;
    }

    /**
     * 获取操作
     *
     * @param sheet
     * @return
     */
    public static String getOperator(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 13);
    }

    /**
     * 获取是否工作日运行
     *
     * @param sheet
     * @return
     */
    public static String getIsWorkRun(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 14);
    }

    /**
     * 获取指定节点
     *
     * @param sheet
     * @return
     */
    public static String getAppointAgentCode(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 15);
    }

    /**
     * 获取是否限定生效日期
     *
     * @param sheet
     * @return
     */
    public static String getIsValidDate(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 16);
    }

    /**
     * 获取生效日期开始日期
     *
     * @param sheet
     * @return
     */
    public static String getStartDate(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 17);
    }

    /**
     * 获取生效日期结束日期
     *
     * @param sheet
     * @return
     */
    public static String getEndDate(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 18);
    }

    /**
     * 获取任务依赖作业
     *
     * @param sheet
     * @return
     */
    public static String getTaskDependJob(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 19);
    }

    /**
     * 获取任务依赖任务
     *
     * @param sheet
     * @return
     */
    public static String getTaskDependTask(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 20);
    }

    /**
     * 获取任务资源数
     *
     * @param sheet
     * @return
     */
    public static String getTaskResNum(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 21);
    }

    /**
     * 获取任务是否顺序执行
     *
     * @param sheet
     * @return
     */
    public static String getTaskIsOrder(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 22);
    }

    /**
     * 获取任务是否是结束任务
     *
     * @param sheet
     * @return
     */
    public static String getTaskIsEnd(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 23);
    }

    /**
     * 获取任务允许出错次数
     *
     * @param sheet
     * @return
     */
    public static String getTaskAllowErrCount(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 24);
    }

    /**
     * 获取任务超时时长
     *
     * @param sheet
     * @return
     */
    public static String getTaskOverPlanDuration(Sheet sheet, int rowIndex) {
        return getValueByRowCeNo(sheet, rowIndex, 25);
    }

    /**
     * @Method: checkJobName
     * @Param: [jobName, rowIndex, dbCycleJobCodeMap, operator]
     * @Return: java.lang.String
     * @Description: 作业名称校验
     * @Author: ji.tang
     * @Date: 2022/6/7 13:53
     * @Version: V1.0
     */
    public static String checkJobName(String jobName, Integer rowIndex) {
        Pattern pattern = Pattern.compile("^[a-zA-Z0-9_\\u4e00-\\u9fa5-()=>._\\s*]+$");
        if (StringUtils.isBlank(jobName)) {
            return "第" + rowIndex + "行的作业名称不能为空!";
        } else {
            Matcher matcher = pattern.matcher(jobName);
            if (!matcher.matches()) {
                return "第" + rowIndex + "行的作业名称不能输入特殊字符";
            } else if (jobName.length() > 100) {
                return "第" + rowIndex + "行的作业名称长度不能大于100位";
            }
        }
        return null;
    }

    /**
     * @Method: checkDateExpression
     * @Param: [dateExpression, rowIndex]
     * @Return: void
     * @Description: 调度间隔校验
     * @Author: ji.tang
     * @Date: 2022/6/7 14:12
     * @Version: V1.0
     */
    public static String checkDateExpression(String isSingleJob, String dateExpression, Integer rowIndex) {
        if (StringUtils.isNotBlank(isSingleJob)) {
            if (Const.IS_SINGLE_JOB_CN.equals(isSingleJob)) {
                if (StringUtils.isNotBlank(dateExpression) && (!Const.JOB_DEF_DATE_EXPRESSION_DAY.equals(dateExpression) ||
                        !Const.JOB_DEF_DATE_EXPRESSION_DAY_CN.equals(dateExpression))) {
                    return "第" + rowIndex + "行单次作业的调度间隔默认是日，不可输入其他字符。";
                }
            }
            if (Const.NOT_SINGLE_JOB_CN.equals(isSingleJob)) {
                if (StringUtils.isNotBlank(dateExpression)) {
                    int index = dateExpression.indexOf("[");
                    dateExpression = (-1 != index) ? dateExpression.substring(0, index) : dateExpression;
                    if (Const.JOB_DEF_DATE_EXPRESSION_DAY_CN.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_DAY.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_WEEK_CN.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_WEEK.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_XUN_CN.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_XUN.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_MONTH_CN.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_MONTH.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_QUARTER_CN.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_QUARTER.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_YEAR_CN.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_YEAR.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_OTHER_CN.equals(dateExpression) ||
                            Const.JOB_DEF_DATE_EXPRESSION_OTHER.equals(dateExpression)) {
                        return null;
                    } else {
                        return "第" + rowIndex + "行的调度间隔日期格式不正确。";
                    }
                }
            }
        }
        return null;
    }

    /**
     * @Method: checkResNum
     * @Param: [resNum, rowIndex]
     * @Return: java.lang.String
     * @Description: 资源数的校验
     * @Author: ji.tang
     * @Date: 2022/6/13 10:36
     * @Version: V1.0
     */
    public static String checkResNum(String resNum, int rowIndex) {
        if (StringUtils.isNotBlank(resNum)) {
            if (Integer.parseInt(resNum) < 1 || Integer.parseInt(resNum) > 100) {
                return "第" + rowIndex + "行的资源数范围须在1-100之间";
            }
        }
        return null;
    }

    /**
     * @Method: checkIsValidDate
     * @Param: [isValidDate, rowIndex]
     * @Return: java.lang.String
     * @Description: 是否限定任务生效日期的校验
     * @Author: ji.tang
     * @Date: 2022/6/13 10:43
     * @Version: V1.0
     */
    public static String checkIsValidDate(String isValidDate, int rowIndex) {
        if (StringUtils.isBlank(isValidDate)) {
            return "第" + rowIndex + "行的是否限定任务生效日期不能为空";
        }
        if (Const.IS_SINGLE_JOB_CN.equals(isValidDate) || Const.NOT_SINGLE_JOB_CN.equals(isValidDate)) {
            return null;
        } else {
            return "第" + rowIndex + "行的是否限定任务生效日期，参数格式为：是/否";
        }
    }

    /**
     * @Method: checkValidDate
     * @Param: [isValidDate, startDate, endDate, rowIndex]
     * @Return: java.lang.String
     * @Description: 限定任务生效日期的校验
     * @Author: ji.tang
     * @Date: 2022/6/13 10:52
     * @Version: V1.0
     */
    public static String checkValidDate(String isValidDate, String startDate, String endDate, int rowIndex) {
        if (StringUtils.isNotBlank(isValidDate)) {
            if (Const.IS_SINGLE_JOB_CN.equals(isValidDate)) {
                if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
                    return "第" + rowIndex + "行的开始时间和结束时间均不能为空";
                } else {
                    //校验日期格式
                    if (!HdrsDateUtil.isValidDate(startDate) || !HdrsDateUtil.isValidDate(endDate)) {
                        return "第" + rowIndex + "行的开始时间和结束时间格式不正确，正确格式：yyyy-MM-dd";
                    } else {
                        if (cn.hutool.core.date.DateUtil.parse(startDate).after(cn.hutool.core.date.DateUtil.parse(endDate))) {
                            return "第" + rowIndex + "行的开始时间必须小于结束时间";
                        }
                    }
                }
            } else if (Const.NOT_SINGLE_JOB_CN.equals(isValidDate)) {
                if (StringUtils.isNotBlank(startDate) || StringUtils.isNotBlank(endDate)) {
                    return "第" + rowIndex + "行的是否限定生效日期为否，所以开始结束时间不需要填写";
                }
            }
        }
        return null;
    }

    /**
     * @Method: checkTaskName
     * @Param: [taskName, rowIndex]
     * @Return: java.lang.String
     * @Description: 任务名称校验
     * @Author: ji.tang
     * @Date: 2022/6/14 17:55
     * @Version: V1.0
     */
    public static String checkTaskName(String taskName, Integer rowIndex) {
        Pattern pattern = Pattern.compile("^[a-zA-Z0-9_\\u4e00-\\u9fa5-()=>._\\s*]+$");
        if (StringUtils.isBlank(taskName)) {
            return "第" + rowIndex + "行的任务名称不能为空!";
        } else {
            Matcher matcher = pattern.matcher(taskName);
            if (!matcher.matches()) {
                return "第" + rowIndex + "行的任务名称不能输入特殊字符";
            }
        }
        return null;
    }
}
